from datetime import date
from typing import Sequence, TypeVar
import pandas as pd
from sqlalchemy import delete, desc, insert, select, text
from sqlalchemy.ext.asyncio import AsyncSession
from module_stock.dao.base_dao import BaseDao
from module_stock.entity.do.macd_base_do import MacdBase
from utils import pd_util

T = TypeVar('T', bound=MacdBase)
class KlineMacdDao(BaseDao[T]):

    @classmethod
    async def get_macds(cls, db: AsyncSession, symbol: str, start_date:date) :
        """
        根据查询参数获取股票k线macd列表信息

        :param db: orm对象
        :param symbol: 股票代码
        :return: 股票k线macd列表信息对象
        """
        query = (
            select(cls.get_model_class())
            .where(
                cls.get_model_class().symbol == symbol if symbol else True,
                cls.get_model_class().trade_date >= start_date if start_date else True
            )
            .order_by(cls.get_model_class().trade_date.asc())
        )
        macd_list = (await db.execute(query)).scalars().all()

        return macd_list
    
    @classmethod
    async def get_macds_pd(cls, db: AsyncSession, symbol: str, start_date:date) :

        macd_list = await cls.get_macds(db, symbol, start_date)
        if macd_list :
            macd_df = pd.DataFrame(pd_util.AsyncORMConverter._orms_to_dicts(macd_list))
            return macd_df
        return pd.DataFrame()
    
    @classmethod
    async def batch_add_macd(cls, db: AsyncSession, macds: list[dict]):
        """
        批量新增股票k线macd信息数据库操作

        :param db: orm对象
        :param kline_macds: 股票k线数据
        :return:        
        """
        st = insert(cls.get_model_class()).values(macds)
        await db.execute(st)

    @classmethod
    async def get_all_symbols(cls, db: AsyncSession):
        """
        获取所有股票代码

        :param db: orm对象
        :return: 股票代码集
        """
        query = (
            select(cls.get_model_class().symbol).distinct()
            .order_by(cls.get_model_class().symbol)
        )

        symbols = (await db.execute(query)).scalars().all()

        return symbols

    @classmethod
    async def batch_delete_macd(cls, db: AsyncSession, symbols):
        """
        批量删除股票macd信息数据库操作

        :param db: orm对象
        :param symbols: 股票代码列表
        :return:
        """
        await db.execute(delete(cls.get_model_class()).where(cls.get_model_class().symbol.in_(symbols)))

    @classmethod
    async def get_last_macd_detail(cls, db: AsyncSession, symbol: str):
        """
        根据股票代码获取数据表最后一个k线macd信息

        :param db: orm对象
        :param symbol: 股票代码
        :return: 股票k线macd信息对象
        """
        macd_info = (
            (
                await db.execute(
                    select(cls.get_model_class()).where(
                        cls.get_model_class().symbol == symbol
                    ).order_by(desc(cls.get_model_class().trade_date)).limit(1)
                )
            )
            .scalars()
            .first()
        )

        return macd_info
    
    @classmethod
    async def delete_macd(cls, db: AsyncSession, symbol: str):
        """
        删除股票日线macd数据库操作

        :param db: orm对象
        :param symbol: 股票代码
        :return:
        """
        await db.execute(delete(cls.get_model_class()).where(
            cls.get_model_class().symbol == symbol
        ))

    @classmethod
    async def clear_macd_dao(cls, db: AsyncSession):
        """
        清空股票周线数据库操作

        :param db: orm对象
        :return:
        """
        table_name = cls.get_model_class().__tablename__
        await db.execute(text(f"truncate table {table_name}"))
    